				function run (func) {
					try {
						func();
					} catch (thrown) {
						console.error(thrown.stack || thrown);
					} finally {
						console.info('run complete');
					}
				}

				new function () {

					function startupTest () {
						
						
						//////////////////////////////////////////////////
						
						/**
						 * @constructor
						 * @extends {SimpleCommand}
						 */
						function DoPrintTextCommand ()
						{
							SimpleCommand.call(this);
						};
						
						DoPrintTextCommand.prototype= new SimpleCommandAdapter;
						DoPrintTextCommand.prototype.constructor= DoPrintTextCommand;
						DoPrintTextCommand.prototype.execute= function (note)
						{
							var paragraph= document.createElement('p');
							paragraph.innerHTML= '> ' + note.getBody();
							document.body.appendChild(paragraph);
						};

						//////////////////////////////////////////////////
						
						/**
						 * @constructor
						 * @extends {SimpleCommand}
						 */
						function SayHaiCommand () 
						{
							SimpleCommand.call(this);
						};
						SayHaiCommand.prototype= new SimpleCommandAdapter;
						SayHaiCommand.prototype.constructor= SayHaiCommand;
						SayHaiCommand.prototype.execute= function (note)
						{
							this.sendNotification(ApplicationFacade.DO_PRINT_TEXT, 'hai');
							this.sendNotification(ApplicationFacade.DO_STOP);
						};
						
						//////////////////////////////////////////////////
						
						/**
						 * @constructor
						 * @extends {PrintTextCommand}
						 */
						function SayBaiCommand () 
						{
							SimpleCommand.call(this);
						};
						SayBaiCommand.prototype= new SimpleCommandAdapter;
						SayBaiCommand.prototype.constructor= SayBaiCommand;					
						SayBaiCommand.prototype.execute= function (note)
						{
							this.sendNotification(ApplicationFacade.DO_PRINT_TEXT, 'bai');
						};
						
						//////////////////////////////////////////////////

						DoStartCommand.prototype= new MacroCommandAdapter;
						DoStartCommand.prototype.constructor= DoStartCommand;
						/** @override */
						DoStartCommand.prototype.initializeMacroCommand= function ()
						{
							this.addSubCommand(SayHaiCommand);
						};
						function DoStartCommand ()
						{
							MacroCommand.call(this);
						};

						//////////////////////////////////////////////////

						DoStopCommand.prototype= new MacroCommandAdapter;
						DoStopCommand.prototype.constructor= DoStopCommand;
						DoStopCommand.prototype.initializeMacroCommand= function ()
						{
							this.addSubCommand(SayBaiCommand);
						};
						
						/** @constructor */
						function DoStopCommand () 
						{
							MacroCommand.call(this);
						};
						
						//////////////////////////////////////////////////
						
						
						
						function ShellView ()
						{
							
						};
						
						ShellView.prototype=
						{
							printText: function (text)
							{
								var paragraph= document.createElement('p');
								paragraph.innerHTML= '> ' + text;
								document.body.appendChild(paragraph);
							}
						}
						
						
						
						/**
						 * @constructor
						 * @inherits {Mediator}
						 */
						function ShellMediator ()
						{
							Mediator.call(this, null, new ShellView);
						};
						
						ShellMediator.prototype= new MediatorAdapter;
						ShellMediator.prototype.constructor= ShellMediator;
						
						/** @override */
						ShellMediator.prototype.listNotificationInterests= function ()
						{
							return [ApplicationFacade.DO_PRINT_TEXT];
						};
						
						/** @override */
						ShellMediator.prototype.handleNotification= function (note)
						{
							console.info(this.getMediatorName() + ' is handling notification ' + note.getName());
							switch (note.getName())
							{
								case ApplicationFacade.DO_PRINT_TEXT :
								{
									console.dir(this.getViewComponent());
									this.viewComponent.printText('> mediated! ' + note.getBody());
								}
							}
						};
						
						/**
						 * @static
						 * @const
						 * @type {string}
						 */
						ShellMediator.NAME= 'ShellMediator';
						
						
						
						
						//////////////////////////////////////////////////

						/**
						 * @static
						 * @const
						 * @type {string}
						 */
						ApplicationFacade.DO_START= "doStart";
						
						/**
						 * @static
						 * @const
						 * @type {string}
						 */
						ApplicationFacade.DO_STOP= "doStop";
						
						/**
						 * @static
						 * @const
						 * @type {string}
						 */
						ApplicationFacade.DO_PRINT_TEXT= "doPrintText";

						/**
						 * @return {ApplicationFacade}
						 */
						ApplicationFacade.getInstance= function () 
						{
							if (ApplicationFacade.instance)
								return ApplicationFacade.instance;

							return ApplicationFacade.instance= new ApplicationFacade;
						};
						
						/**
						 * @constructor
						 * @extends {Facade}
						 */
						function ApplicationFacade () 
						{
							this.initializeFacade();
						};

						ApplicationFacade.prototype= new FacadeAdapter;
						ApplicationFacade.constructor= ApplicationFacade;

						/** @override */
						ApplicationFacade.prototype.initializeController= function () {
							Facade.prototype.initializeController.call(this);
							this.registerCommand(ApplicationFacade.DO_START, DoStartCommand);
							this.registerCommand(ApplicationFacade.DO_PRINT_TEXT, DoPrintTextCommand);
							this.registerCommand(ApplicationFacade.DO_STOP, DoStopCommand);
						};
						
						ApplicationFacade.prototype.initializeView= function ()
						{
							Facade.prototype.initializeView.call(this);
							this.registerMediator(new ShellMediator);
						}
						
						/**
						 * @private
						 * @type {boolean}
						 */
						ApplicationFacade.prototype.started= false;
						
						/**
						 * 
						 * @return {void}
						 */
						ApplicationFacade.prototype.start= function ()
						{
							if (this.started)
								return;
								
							console.log('starting');	
							this.started= true;
							this.sendNotification(ApplicationFacade.DO_START);
							this.removeCommand(ApplicationFacade.DO_START);
						};
						
						
						//////////////////////////////////////////////////
						ApplicationFacade.getInstance().start();
					};

					run(startupTest);
				};